package util

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

type TokenManager interface {
	GetToken(account string)
	GetAccount(token string)
	GetTime(account string)
	UpdateToken(account string)
}

type MultipleTokenUtil struct {
	tokenTime   map[string]int64    // 用户的token的更新时间
	userToken   map[string][]string // 用户的token
	tokenUser   map[string]string   // token对应的用户账号
	letters     []rune
	tokenLength int
	tokenCount  int
	mutex       sync.Mutex
}

// RandSeq 获取随机字符串
func (t *MultipleTokenUtil) RandSeq(n int) string {
	b := make([]rune, n)
	for i := range b {
		b[i] = t.letters[rand.Intn(len(t.letters))]
	}
	return string(b)
}

// GetToken 获取该账户的token
func (t *MultipleTokenUtil) GetToken(account string) string {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	// 正常情况下不会出现这种情况
	if len(t.userToken[account]) == 0 {
		return ""
	}
	return t.userToken[account][len(t.userToken[account])-1]
}

// GetAccount 获取该token对应账户
func (t *MultipleTokenUtil) GetAccount(token string) string {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	return t.tokenUser[token]
}

// GetTime 获取该token的创建时间
func (t *MultipleTokenUtil) GetTime(token string) int64 {
	t.mutex.Lock()
	defer t.mutex.Unlock()
	return t.tokenTime[token]
}

// UpdateToken 为某个用户 更新 或 创建 token
func (t *MultipleTokenUtil) UpdateToken(account string) string {
	//加互斥锁
	t.mutex.Lock()
	// 释放锁
	defer t.mutex.Unlock()

	// 生成新token
	newToken := t.RandSeq(t.tokenLength)
	for t.tokenUser[newToken] != "" {
		newToken = t.RandSeq(t.tokenLength)
	}
	t.userToken[account] = append(t.userToken[account], newToken)
	t.tokenTime[newToken] = time.Now().UnixMilli()
	t.tokenUser[newToken] = account

	// 如果token数量大于tokenCount 则删除第一个token
	if len(t.userToken[account]) > t.tokenCount {
		delete(t.tokenTime, t.userToken[account][0])
		delete(t.tokenUser, t.userToken[account][0])
		t.userToken[account] = t.userToken[account][1:]
	}
	return newToken
}
func (t *MultipleTokenUtil) PrintOut() {
	fmt.Println("tokenTime")
	for i := range t.tokenTime {
		fmt.Println(i, t.tokenTime[i])
	}
	fmt.Println("userToken")
	for i := range t.userToken {
		fmt.Println(i, t.userToken[i])
	}

	fmt.Println("tokenUser")
	for i := range t.tokenUser {
		fmt.Println(i, t.tokenUser[i])
	}
}

// UserTokenUtil 管理用户token
var UserTokenUtil = &MultipleTokenUtil{
	tokenTime:   make(map[string]int64),
	userToken:   make(map[string][]string), // 用户的token
	tokenUser:   make(map[string]string),   // token对应的用户账号
	letters:     []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),
	tokenLength: 50,
	tokenCount:  5,
}

// OtherUtil 随机字符串
var OtherUtil = &MultipleTokenUtil{
	tokenTime:   make(map[string]int64),
	userToken:   make(map[string][]string), // 用户的token
	tokenUser:   make(map[string]string),   // token对应的用户账号
	letters:     []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),
	tokenLength: 50,
	tokenCount:  1,
}
var TestMultipleToken = &MultipleTokenUtil{
	tokenTime:   make(map[string]int64),
	userToken:   make(map[string][]string), // 用户的token
	tokenUser:   make(map[string]string),   // token对应的用户账号
	letters:     []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"),
	tokenLength: 50,
	tokenCount:  4,
}
